package com.yunji.order.business.remote;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.yunji.common.cache.RedisCache;
import com.yunji.common.utils.StringUtils;
import com.yunji.common.utils.TimeUtils;
import com.yunji.common.utils.bean.BeanUtils;
import com.yunji.common.utils.http.HttpUtils;
import com.yunji.order.domain.OrderDO;
import com.yunji.order.domain.RequestDO;
import com.yunji.order.emuns.PayMode;
import com.yunji.order.emuns.RemoteTypes;
import com.yunji.order.emuns.ResultTypes;
import com.yunji.order.service.RequestService;
import com.yunji.system.context.SystemUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.TimeUnit;

import static com.yunji.order.contstant.PayCode.WECHAT_ACCESS_TOKEN;
import static com.yunji.order.contstant.PayCode.WECHAT_ORDER_LOGISTICS;
import static com.yunji.order.contstant.WechatCode.WECHAT_CREDENTIAL_TOKEN;

/**
 * @Project: yunji-coffee
 * @Package: com.yunji.order.remote
 * @Title: WechatDelivered
 * @Description: 微信交付业务处理
 * <p>
 * History:
 * Date						Version			Author			Summary
 * ========================================================================
 * 2024-04-20 11:18:36		V1.0			HuaAo		新建类
 */
@Component
public class WechatDelivered {
    private static final Logger logs = LoggerFactory.getLogger(WechatDelivered.class);

    @Value("${wechat.member.appid:xxx}")
    private String memberAppid;
    @Value("${wechat.member.secret:xxx}")
    private String memberSecret;
    @Value("${wechat.credential.refresh:false}")
    private boolean refresh;
    @Resource
    private RequestService requestService;

    /**
     * @return String 微信凭证Token
     * @Title getCredentialToken
     * @Desc 获取凭证token
     * @Date 2024-04-20 12:02:00.589
     */
    private String getCredentialToken() {
        String key = WECHAT_CREDENTIAL_TOKEN + memberAppid + "_" + memberSecret;
        if (Boolean.TRUE.equals(SystemUtil.redisCache().hasKey(key))) {
            return SystemUtil.redisCache().get(key);
        }
        // 用频率限制为 1万次 每分钟，每天限制调用 50万 次
        // 不能直接使用map
        HashMap<String, Object> param = new JSONObject();
        param.put("grant_type", "client_credential");
        param.put("appid", memberAppid);
        param.put("secret", memberSecret);
        param.put("force_refresh", refresh);
        String params = JSON.toJSONString(param);
        String url = WECHAT_ACCESS_TOKEN;
        logs.info("【微信凭据】API: url {},参数:{}", url, params);
        String s = HttpUtils.json(url, params);
        JSONObject result = JSONObject.parseObject(s);
        logs.info("【微信凭据】API: 返回 {}", result);

        Assert.isTrue(result.containsKey("access_token"), StringUtils.format("【微信凭据】错误码:{}, 错误信息:{}", result.getString("errcode"), result.getString("errmsg")));
        String token = result.getString("access_token");
        Integer time = BeanUtils.getInteger(result.getInteger("expires_in"), 7200);
        SystemUtil.redisCache().set(key, token, time, TimeUnit.SECONDS);
        return token;
    }

    /**
     * @Title wechatLogistics
     * @Desc 发送微信物流信息
     * @Date 2024-04-20 12:43:18.426
     */
    public void wechatLogistics(OrderDO order) {
        RequestDO request = new RequestDO();
        request.setChannel(PayMode.WECHAT.getCode());
        request.setRequestType(RemoteTypes.WECHAT_TRADE_DELIVERED.getCode());
        request.setTradeCode(order.getOrderCode());
        try {
            String token = getCredentialToken();
            logs.info("【微信物流】,微信Token:{}", token);
            Assert.isTrue(BeanUtils.isNotNull(token), "获取微信Token失败");

            String url = StringUtils.format(WECHAT_ORDER_LOGISTICS, token);
            request.setRequestUrl(url);

            Map<String, Object> param = new HashMap<>();

            param.put("delivery_mode", 1); // 1、统一发货
            param.put("logistics_type", 4); // 用户自提
            Map<String, Object> orderParam = new HashMap<>();
            orderParam.put("order_number_type", 2); // 微信交易流水号
            orderParam.put("transaction_id", order.getPayCode());
            param.put("order_key", orderParam);

            Map<String, Object> payerParam = new HashMap<>();
            payerParam.put("openid", order.getOpenId());
            param.put("payer", payerParam);

            List<Map<String, Object>> list = new ArrayList<>();
            Map<String, Object> shipping = new HashMap<>();
            //FIXME 这里多个商品
            //shipping.put("item_desc", order.getProductName());
            list.add(shipping);
            param.put("shipping_list", list);

            param.put("upload_time", TimeUtils.zoneDate());
            logs.info("【微信物流】微信参数信息：{}", param);
            String params = JSONObject.toJSONString(param);
            request.setRequestParam(params);
            String resp = HttpUtils.json(url, JSONObject.toJSONString(param));
            request.setResponseContent(resp);
            request.setStatus(ResultTypes.SUCCESS.getCode());
            JSONObject result = JSONObject.parseObject(resp);
            Long code = BeanUtils.getLong(result.getInteger("errcode"), 999999999L);
            request.setResponseCode(String.valueOf(code));
            if (Objects.equals(code, 40001L)) {
                String key = WECHAT_CREDENTIAL_TOKEN + memberAppid + "_" + memberSecret;
                SystemUtil.redisCache().delete(key);
            }
            Assert.isTrue(Objects.equals(code, 0L), "发货失败");
            logs.info("【微信物流】响应结果:{}", resp);
        } catch (Exception e) {
            logs.error("微信发货失败");
        } finally {
            request.setStatus(ResultTypes.FINISH.getCode());
            requestService.createRequest(request);
        }
    }
}
